// 打印类属性、方法定义
import { saveAs } from "file-saver";

const WordExport = function (dom, options) {
  if (!(this instanceof WordExport)) return new WordExport(dom, options);

  this.options = this.extend(
    {
      noPrint: ".no-print",
      isParent: false,
      fileName: "Word-Export",
      maxWidth: 624,
    },
    options
  );

  let originalDom;
  if (typeof dom === "string") {
    originalDom = document.querySelector(dom);
  } else {
    originalDom = this.isDOM(dom) ? dom : dom.$el;
  }

  this.dom = originalDom.cloneNode(true)

  this.init();
};
WordExport.prototype = {
  init () {
    // var content = this.getStyle() + this.getHtml();
    var content =  this.getHtml();
    this.toExport(content);
  },
  extend: function (obj, obj2) {
    for (var k in obj2) {
      obj[k] = obj2[k];
    }
    return obj;
  },

  getStyle: function () {
    var str = "",
      styles = document.querySelectorAll("style,link");
    for (var i = 0; i < styles.length; i++) {
      str += styles[i].outerHTML;
    }
    str += "<style>" + (this.options.noPrint ? this.options.noPrint : ".no-print") + "{display:none;}</style>";
    str += `<style media="print">
      @page {
        size: auto;
        margin: 0mm;
      }
    </style>`;

    return str;
  },

  getHtml () {
    var inputs = document.querySelectorAll("input");
    var textareas = document.querySelectorAll("textarea");
    var selects = document.querySelectorAll("select");

    for (var k = 0; k < inputs.length; k++) {
      if (inputs[k].type == "checkbox" || inputs[k].type == "radio") {
        if (inputs[k].checked == true) {
          inputs[k].setAttribute("checked", "checked");
        } else {
          inputs[k].removeAttribute("checked");
        }
      } else if (inputs[k].type == "text") {
        inputs[k].setAttribute("value", inputs[k].value);
      } else {
        inputs[k].setAttribute("value", inputs[k].value);
      }
    }

    for (var k2 = 0; k2 < textareas.length; k2++) {
      if (textareas[k2].type == "textarea") {
        textareas[k2].innerHTML = textareas[k2].value;
      }
    }

    for (var k3 = 0; k3 < selects.length; k3++) {
      if (selects[k3].type == "select-one") {
        var child = selects[k3].children;
        for (var i in child) {
          if (child[i].tagName == "OPTION") {
            if (child[i].selected == true) {
              child[i].setAttribute("selected", "selected");
            } else {
              child[i].removeAttribute("selected");
            }
          }
        }
      }
    }

    let outerDom = this.wrapperRefDom(this.dom); // 获取当前需要打印的节点元素
    outerDom = this.filterDom(outerDom); // 过滤掉不需要显示的元素
    outerDom = this.formatImage(outerDom); // 过滤掉不需要显示的元素
    // outerDom = this.latexImageToMathML(outerDom); // latex语法图片，替换为word解析的公式
    let outerHTML = outerDom.outerHTML;
    return outerHTML;
  },
  // 向父级元素循环，包裹当前需要打印的元素
  // 防止根级别开头的 css 选择器不生效
  wrapperRefDom: function (refDom) {
    let prevDom = null;
    let currDom = refDom;
    // 判断当前元素是否在 body 中，不在文档中则直接返回该节点
    if (!this.isInBody(currDom)) return currDom;

    if (!this.options.isParent) return currDom;

    while (currDom) {
      if (prevDom) {
        let element = currDom.cloneNode(false);
        element.appendChild(prevDom);
        prevDom = element;
      } else {
        prevDom = currDom.cloneNode(true);
      }

      currDom = currDom.parentElement;
    }

    return prevDom;
  },
  filterDom(refDom) {
    let noPrints = refDom.querySelectorAll(this.options.noPrint || ".no-print");
    noPrints.forEach((element) => {
      element.remove();
    });
    return refDom;
  },
  formatImage(refDom) {
    let latexImages = refDom.querySelectorAll('img');
    for(let i = 0; i < latexImages.length; i++) {
        latexImages[i].style.verticalAlign = 'middle';
    }
    return refDom;
  },
  latexImageToMathML(refDom) {
    let latexImages = refDom.querySelectorAll('img[data-latex]');
    for(let i = 0; i < latexImages.length; i++) {
      const content = latexImages[i].getAttribute('data-latex');
      latexImages[i].outerHTML = MathJax.tex2mml(content, {display: false})
    }

    return refDom;
  },
  latexToMathML(content) {
    return new Promise((resolve, reject) => {
      MathJax.texReset();
      MathJax.tex2mmlPromise(content, {display: false}).then(function (mml) {
        resolve(mml)
      }).catch(function (err) {
        resolve(err)
      })
    })
  },
  toExport(content) {
    // <style>
    //     <!--横向/分栏、、、
    //     @page WordSection1{
    //       size:841.9pt 595.3pt;
    //       mso-page-orientation:landscape;
    //       margin:90.0pt 72.0pt 90.0pt 72.0pt;
    //       mso-columns: 2 even 21.25pt;
    //     }
    //     div.WordSection1 {page:WordSection1;}
    //     -->
    //   </style>
    let outerHTML = `<!DOCTYPE html>
    <head>
    <meta charset="utf-8">
  </head>
  <body>
    <div class="word">
      <style>
        p {
          mso-style-name: 正文;
          mso-style-parent: '';
          margin: 0pt;
          margin-bottom: 0pt;
          mso-pagination: none;
          text-align: justify;
          text-justify: inter-ideograph;
          font-family: Calibri;
          mso-fareast-font-family: 宋体;
          mso-bidi-font-family: 'Times New Roman';
          font-size: 10.5pt;
          mso-font-kerning: 1pt;
        }
      </style>
      <div class=WordSection1>
        ${content}
      </div>
    </div>
    </body>
</html>
    `;
    console.log(outerHTML)
    let blob = htmlDocx.asBlob(outerHTML, {orientation: 'portrait'});
    saveAs(blob, this.options.fileName + ".docx");
  },
  // 检查一个元素是否是 body 元素的后代元素且非 body 元素本身
  isInBody: function (node) {
    return node === document.body ? false : document.body.contains(node);
  },
  isDOM:
    typeof HTMLElement === "object"
      ? function (obj) {
          return obj instanceof HTMLElement;
        }
      : function (obj) {
          return obj && typeof obj === "object" && obj.nodeType === 1 && typeof obj.nodeName === "string";
        },
};
const MyPlugin = {};
MyPlugin.install = function (Vue, options) {
  Vue.prototype.$wordExport = WordExport;
};
export default MyPlugin;
